package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.cache.vo.TravelStatisVO;
import cn.wolfcode.luowowo.domain.Destination;
import cn.wolfcode.luowowo.domain.Strategy;
import cn.wolfcode.luowowo.domain.Travel;
import cn.wolfcode.luowowo.domain.UserInfo;
import cn.wolfcode.luowowo.query.TravelCondition;
import cn.wolfcode.luowowo.query.TravelQuery;
import cn.wolfcode.luowowo.repository.TravelRepository;
import cn.wolfcode.luowowo.service.IDestinationService;
import cn.wolfcode.luowowo.service.IStrategyService;
import cn.wolfcode.luowowo.service.ITravelsService;
import cn.wolfcode.luowowo.service.IUserInfoService;
import cn.wolfcode.luowowo.util.DBHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Optional;

@Service
public class TravelsServiceImpl implements ITravelsService {
    @Autowired
    private TravelRepository travelRepository;
    @Autowired
    private MongoTemplate template;
    @Autowired
    private IUserInfoService userInfoService;
    @Autowired
    private IDestinationService destinationService;
    @Autowired
    private IStrategyService strategyService;
    @Override
    public Travel get(String id) {
        /*Optional<Travel> op = travelRepository.findById(id);
        if(op.isPresent()){
            Travel travel = op.get();
            travel.setAuthor(userInfoService.get(travel.getUserId()));
            travel.setDest(destinationService.select(travel.getDestId()));
            return travel;
        }*/
        Travel travel = travelRepository.findById(id).orElse(null);
        travel.setAuthor(userInfoService.get(travel.getUserId()));
        travel.setDest(destinationService.select(travel.getDestId()));
        return travel;
    }

    @Override
    public void delete(String id) {
        travelRepository.deleteById(id);
    }

    @Override
    public void save(Travel travel) {
        travel.setId(null);
        travelRepository.save(travel);
    }

    @Override
    public void update(Travel travel) {
        travelRepository.save(travel);
    }

    @Override
    public List<Travel> list() {
        return travelRepository.findAll();
    }

    @Override
    public Page<Travel> query(TravelQuery qo, UserInfo user) {
        //查询条件
        Query query = new Query();
        //高级查询条件

        //查看公开的游记(isPublic)
        //  如果没登录，  查询   发布 + 公开的游记
        /*if(user == null){
            query.addCriteria(new Criteria().andOperator(
                    Criteria.where("isPublic").is(Travel.ISPUBLIC_YES),
                    Criteria.where("state").is(Travel.STATE_RELEASE)
            ));
        }else{
            //  如果登录了，  查询   别人发布 + 公开的游记
            //还有查询自己所有的游记
            query.addCriteria(new Criteria().
                    orOperator(
                            new Criteria().andOperator(
                                    Criteria.where("isPublic").is(Travel.ISPUBLIC_YES),
                                    Criteria.where("userId").ne(user.getId()),
                                    Criteria.where("state").is(Travel.STATE_RELEASE)
                            ),
                    Criteria.where("userId").is(user.getId()))
            );
        }*/

        //当state不为-1时才添加高级查询条件
        if (qo.getState() != -1) {
            query.addCriteria(Criteria.where("state").is(qo.getState()));
        }
        //当前qo中的destId不为空时
        if (StringUtils.hasLength(qo.getDestId())) {
            query.addCriteria(Criteria.where("destId").is(qo.getDestId()));
        }
        TravelCondition day = qo.getDays();
        TravelCondition perexpend = qo.getPerExpends();
        //人均消费
        if (day != null) {
            query.addCriteria(Criteria.where("day").gte(day.getMin()).lte(day.getMax()));
        }
        //花费天数
        if (perexpend != null) {
            query.addCriteria(Criteria.where("perExpend").gte(perexpend.getMin()).lte(perexpend.getMax()));
        }
        //当排序中选定最新或者最热时
        PageRequest pageable;
        if (qo.getOrderType() == 1) {
            pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(),
                    Sort.Direction.DESC, "createTime");
        } else {
            pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(),
                    Sort.Direction.DESC, "viewnum");
        }
        Page<Travel> page = DBHelper.query(template, Travel.class, query, pageable);
        for (Travel travel : page) {
            UserInfo userInfo = userInfoService.get(travel.getUserId());
            travel.setAuthor(userInfo);
        }
        return page;
    }

    @Override
    public void changeState(String id, int state) {
        Travel travel = this.get(id);
        //最后更新时间改动
        travel.setLastUpdateTime(new Date());
        //发布时间改动
        travel.setReleaseTime(new Date());
        //1.查询要审核的游记是否存在
        //2.判断审核游记是否是待审核状态
        if (travel != null) {
            //3.审核通过之后需要做什么
            if (travel.getState() == Travel.STATE_WAITING) {
                //  a)审核状态改审核通过(已发布)
                travel.setState(state);
                //4.审核拒绝之后需要做什么()
            } else if (travel.getState() == Travel.STATE_RELEASE) {
                //  a)审核状态改审核拒绝
                travel.setState(state);
            }

            //下架改上架(当state为下架状态)
            if (travel.getState() == Travel.STATE_OFFSHELF) {
                travel.setState(state);
                //上架改下架(当state为上架状态)
            } else if (travel.getState() == Travel.STATE_RELEASE) {
                travel.setState(state);
            }
        }
        //5.记录审核信息(审核人,审核状态,审核意见,审核时间)
        this.update(travel);
    }

    @Override
    public void saveOrUpdate(Travel travel) {
        //目的地name
        travel.setDestName(destinationService.
                select(travel.getDestId()).
                getName());
        //当前登录用户
        //最后更新时间
        travel.setLastUpdateTime(new Date());
        //创建时间
        travel.setCreateTime(new Date());

        if (StringUtils.hasLength(travel.getId())) {
            Travel travel1 = this.get(travel.getId());
            travel.setViewnum(travel1.getViewnum());//点击/阅读数
            travel.setReplynum(travel1.getReplynum());//回复数
            travel.setFavornum(travel1.getFavornum());//收藏数
            travel.setSharenum(travel1.getSharenum());//分享数
            travel.setThumbsupnum(travel1.getThumbsupnum());//点赞数
            this.update(travel);
        } else {
            this.save(travel);
        }
    }

    @Override
    public List<Destination> getDest(String destId) {
        Pageable pageable = PageRequest.of(0,3, Sort.Direction.DESC,"viewnum");
        return travelRepository.findByDestId(destId,pageable);
    }

    @Override
    public UserInfo getUser(String tid) {
        Travel travel = this.get(tid);
        UserInfo userInfo = userInfoService.get(travel.getUserId());
        return userInfo;
    }

    @Override
    public Page<Strategy> getViewnum5() {
        Query query = new Query();
        Pageable pageable = PageRequest.of(0,5, Sort.Direction.DESC,"viewnum");
        return DBHelper.query(template, Strategy.class, query, pageable);
    }

    @Override
    public void updateVO(TravelStatisVO travelStatisVO) {
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(travelStatisVO.getTravelId()));
        Update update = new Update();
        update.set("viewnum",travelStatisVO.getViewnum());
        update.set("replynum",travelStatisVO.getReplynum());
        update.set("favornum",travelStatisVO.getFavornum());
        update.set("sharenum",travelStatisVO.getSharenum());
        update.set("thumbsupnum",travelStatisVO.getThumbsupnum());
        //部分字段更新
        template.updateMulti(query,update,Travel.class);
    }

    @Override
    public List<Travel> getByDestName(String destName) {
        List<Travel> travels = travelRepository.findByDestName(destName);
        for (Travel travel : travels) {
            UserInfo userInfo = userInfoService.get(travel.getUserId());
            travel.setAuthor(userInfo);
        }
        return travels;
    }
}
